package model;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;

import javax.imageio.ImageIO;

import model.CommandNode;

public class Model{

	List<Turtle> myTurtles = new ArrayList<Turtle>();
	List<Trail> myTrails = new ArrayList<Trail>(); 
	World myWorld;
	//Parser sLogoParser = new Parser();

	public final static String TURTLE_OBSERVER = "TURTLE";
	public final static String WORLD_OBSERVER = "WORLD";
	//final static String FUNCTION_OBSERVER = "FUNCTION";
	//final static String VARIABLE_OBSERVER = "VARIABLE";
	Map<String, ArrayList<Observer>> ourObservers = new HashMap<String, ArrayList<Observer>>();
	
	public Model() {
		Turtle defaultTurtle = new Turtle(this);
		myTurtles.add(defaultTurtle);
		myWorld = new World(this,300,300,"src/resources/images/DefaultBG.png");
		myWorld.addModelObserver(this);
	}
	
	
	// TODO: Make this just take one string, not a list
	public void runInput(String input) 
	{
		// Takes input in the form of Strings, parses them into trees of
		// Commands, then runs the
		// Commands

		
		/*
		List<String[]> tokens = new ArrayList<String[]>();
		for (String s : inputList) {
			tokens.add(sLogoParser.tokenize(s));

		}

		List<CommandNode> commandTrees = sLogoParser.assembleTree(tokens);

		for (CommandNode cn : commandTrees) {
			cn.execute();
		}
		*/
		
		return;
	}

	public Turtle getTurtle(int turtleId) {
		return myTurtles.get(turtleId);
	}
	
	public Collection<Turtle> getAllTurtles() {
		return myTurtles;
	}

	public Dimension getWorldBounds(){
		return myWorld.getBounds();
	}
	
	public void deleteTurtle(Turtle t){
		myTurtles.remove(t);
	}
	
	public void addTurtle(){
		myTurtles.add(new Turtle(this));
	}

	public Collection<Trail> getAllTrails() {
		List<Trail> allTrails = new ArrayList<Trail>();

		allTrails.addAll(myTrails);
		for (Turtle jim : myTurtles) {
			allTrails.add(jim.getActiveTrail());
		}

		return allTrails;
	}
	
	public void addTrail(Trail trail){
		myTrails.add(trail);
	}
	// TODO: implement this method.
	public String getBackgroundImagePath() {
			return myWorld.getBackgroundImagePath();
	}
	
	public void setBackground(String path) {
		myWorld.setBackgroundImage(path);
	}
	
	public BufferedImage getBackgroundImage(){
		return myWorld.getBackgroundImage();
	}

	public void addObserver(String key, Observer ob)
	{
		if(ourObservers.containsKey(key)){
			ourObservers.get(key).add(ob);
		}
		else{
			ArrayList<Observer> newObserverType = new ArrayList<Observer>();
			newObserverType.add(ob);
			ourObservers.put(key, newObserverType);
		}
	}

	public void notifyObservers(String key) {
		for(Observer o: ourObservers.get(key)){
			o.update(null, null);
		}
	}
	
}
